package com.pubinfo.passbook.api.controller.bill;

import com.pubinfo.passbook.api.eip.UserInfoService;
import com.pubinfo.passbook.common.entity.TRabbitmqPersonConvert;
import com.pubinfo.passbook.common.exception.ServiceException;
import com.pubinfo.passbook.common.model.bo.eip.ReceiveTaskParam;
import com.pubinfo.passbook.common.model.bo.eip.ReceiveTaskResult;
import com.pubinfo.passbook.common.model.http.eip.UserInfo;
import com.pubinfo.passbook.common.model.vo.base.JsonResult;
import com.pubinfo.passbook.common.model.vo.base.ResultCode;
import com.pubinfo.passbook.common.model.vo.system.UserRoleVo;
import com.pubinfo.passbook.common.service.dubbo.DubboService;
import com.pubinfo.passbook.common.service.master.TRabbitmqPersonConvertService;
import com.pubinfo.passbook.common.utils.HttpUtils;
import com.zjhc.util.DESCodec;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;

import static com.pubinfo.passbook.common.model.constant.RoleEnum.CONTRACT_ADMIN;
import static com.pubinfo.passbook.common.utils.SessionCookieUtils.getHttpServletRequest;

/**
 * @author zhouch
 * @date 2021/11/16 16:11
 */
@Controller
@Api(tags = "EIP登录")
@Slf4j
public class EipAuthController {
    
    @Autowired
    TRabbitmqPersonConvertService personConvertService;
    @Autowired
    DubboService dubboService;
    /**
     * EIP登录信息的DES加密密钥
     */
    private final String SEND_USERNAME_KEY = "USERNAME_SEND_SYSTEM";
    
    @Value(
        "${eip.cas.cas-server-login-url}"
    )
    private String casServerLoginUrl;

    private final String loginUrl = "login_redirect/";

    @Value(
            "${eip.cas.front-forward-enabled}"
    )
    private Boolean frontForwardEnabled;

    @Resource
    UserInfoService userInfoService;

    /**
     * 登錄EIP地址
     *
     * @param selfHost
     * @return
     */
    @GetMapping("/eip/login")
    @ApiOperation("前端跳转到该地址登录")
    public ModelAndView eipLogin(@RequestHeader("Host") String selfHost, @RequestHeader("Referer") String frontUrl) { // 自身服務器地址

        if (frontForwardEnabled) {
            // EIP登录地址
            // 前端IP/backend-api -> 后端IP/api
            return new ModelAndView("redirect:" + casServerLoginUrl + "?TARGET=" + frontUrl + "backend-api/eip/callback/?frontUrl=" + frontUrl);
        } else {
            return new ModelAndView("redirect:" + casServerLoginUrl + "?TARGET=" + "http://" + selfHost + "/api/eip/callback/?frontUrl=" + frontUrl);
        }
    }

    /**
     * 登錄回調地址
     *
     * @return
     */
    @PostMapping("/eip/callback/")
    @ApiOperation("EIP登录回调地址")
    public ModelAndView eipData(
            @RequestParam("frontUrl") String frontUrl, // 前端地址

            /**
             * 该处参数需要
             */
            @RequestParam("userDetailInfo") String userDetailInfo,
            @RequestParam("SAMLart") String samLart,
            @RequestParam("userName") String username
    ) {

        /**
         * 登录返回信息解密逻辑来自
         * org.jasig.cas.client.validation.AbstractTicketValidationFilter
         */
        try {
            String realUsername = DESCodec.decrypt(username, SEND_USERNAME_KEY);
            String realUserInfo = DESCodec.decrypt(userDetailInfo, SEND_USERNAME_KEY);

            log.info("登录用户: " + realUsername);
            log.info("用户信息: " + realUserInfo);
    
            if (realUserInfo.contentEquals("\"\"")) {
                throw new ServiceException("该" + realUsername + "用户的EIP用户信息数据为空.");
            }
    
            UserInfo userinfo = UserInfo.formStr(realUserInfo);
            // 获取角色
            String jthrLoginName = userinfo.getJthrLoginName();
            setUserInfo(userinfo, jthrLoginName);
            String acct = jthrLoginName.substring(0, jthrLoginName.indexOf("@"));
            userinfo.setOrgBizName(userInfoService.orgBizNameByAcct(acct));
            userInfoService.setCurrentUserInfo(samLart, userinfo);
        } catch (Exception e) {
            e.printStackTrace();
        }
    
        return new ModelAndView("redirect:" + frontUrl + loginUrl + samLart);
    }
    
    private void setUserInfo(UserInfo userinfo, String acct) {
        UserRoleVo role = userInfoService.getCurrentUserRoleByNoLogin(acct);
        userinfo.setNsrsbh(role.getNsrsbh());
        userinfo.setRoleCode(role.getRoleCode());
        userinfo.setOrgId(role.getOrgId());
        userinfo.setUserRoleId(role.getUserRoleId());
    }
    
    /**
     * 当前登录的用户信息
     *
     * @return
     */
    @GetMapping("/eip/userinfo")
    @ApiOperation("当前登录用户信息")
    @ResponseBody
    public JsonResult<UserInfo> userInfo(@RequestHeader("token") String token) {
        return JsonResult.success(userInfoService.getCurrentUserInfo(token));
    }
    
    @GetMapping("/login/other/{acct}")
    @ApiOperation("登录其他用户")
    @ResponseBody
    public JsonResult<UserInfo> loginOther(@PathVariable("acct") String acct) {
        UserInfo sourceUser = userInfoService.getCurrentUserInfo();
        TRabbitmqPersonConvert personConvert = personConvertService.getPersonByAcct(acct);
        UserInfo userInfo = new UserInfo();
        //不是管理员，报异常 ，如果已经切换过，需要到Json数据里面查询
        if (!CONTRACT_ADMIN.getRoleCode().equals(sourceUser.getRoleCode()) && StringUtils.isBlank(sourceUser.getUserInfoSource())) {
            throw new ServiceException(ResultCode.FORBIDDEN);
        }
        userInfo.setRealname(personConvert.getTbCert().get(0).getCertName()).setJthrLoginName(acct + "@ZJ");
        //如果没有切换登录过，则设置json  取currentAcct,已经切换登录过不设置
        if (StringUtils.isBlank(sourceUser.getLoginSourceAcct())) {
            userInfo.setUserInfoSource(sourceUser.toString()).setLoginSourceAcct(userInfoService.getCurrentAcct()).setLoginSourceName(sourceUser.getRealname());
        } else {
            userInfo.setUserInfoSource(sourceUser.getUserInfoSource()).setLoginSourceAcct(sourceUser.getLoginSourceAcct()).setLoginSourceName(sourceUser.getLoginSourceName());
        }
        setUserInfo(userInfo, acct);
        userInfo.setOrgBizName(userInfoService.orgBizNameByAcct(acct));
        String token = HttpUtils.getToken(getHttpServletRequest());
        userInfoService.setCurrentUserInfo(token, userInfo);
        return JsonResult.success(userInfo);
    }
    
    @GetMapping("/login/other/exit")
    @ApiOperation("退出其他用户")
    @ResponseBody
    public JsonResult<UserInfo> exit() {
        UserInfo sourceUser = userInfoService.getCurrentUserInfo();
        UserInfo userInfo = UserInfo.formStr(sourceUser.getUserInfoSource());
        String token = HttpUtils.getToken(getHttpServletRequest());
        userInfoService.setCurrentUserInfo(token, userInfo);
        return JsonResult.success(userInfo);
    }
    
    /**
     * 当前登录的用户信息
     *
     * @return
     */
    @GetMapping("/eip/user")
    @ApiOperation("当前登录用户信息")
    @ResponseBody
    public JsonResult<UserInfo> userInfo() {
        return JsonResult.success(userInfoService.getCurrentUserInfo());
    }

    @PostMapping("receiveTaskInfo")
    @ApiOperation(value = "待办更新接口")
    @ResponseBody
    public ReceiveTaskResult sendShortMessage(@RequestBody ReceiveTaskParam taskParam) {
        return dubboService.receiveTaskInfo(taskParam);
    }

    @PostMapping("finishedTask")
    @ApiOperation(value = "待办清除接口")
    @ResponseBody
    public ReceiveTaskResult finishedTask(@RequestBody String taskId) {
        return dubboService.finishedTask(taskId);
    }
}
